Update to libsepol 2.1.8. Change-Id: I7d848ee312d4c706162a822d2031f37a5557ed5f Signed-off-by: Stephen Smalley <sds@tycho.nsa.gov> 
diff --git a/ChangeLog b/ChangeLog index f835678..75bf7b4 100644 --- a/ChangeLog +++ b/ChangeLog 
@@ -1,3 +1,22 @@ +2.1.8 2011-09-13 +	* fix neverallow checking on attributes +	* Move context_copy() after switch block in ocontext_copy_*(). +	* check for missing initial SID labeling statement. +	* Add always_check_network policy capability +	* role_fix_callback skips out-of-scope roles during expansion. + +2.1.7 2011-06-28 +	* reserve policycapability for redhat testing of ptrace child +	* cosmetic changes to make the source easier to read +	* prepend instead of append to filename_trans list +	* Android/MacOS X build support + +2.1.6 2011-04-23 +	* allocate enough space to hold filename in trans rules + +2.1.5 2011-03-28 +	* checkpolicy: implement new default labeling behaviors +  2.1.4 2011-10-03 	* regenerate .pc on VERSION change 	* Move ebitmap_* functions from mcstrans to libsepol 
diff --git a/VERSION b/VERSION index 7d2ed7c..ebf14b4 100644 --- a/VERSION +++ b/VERSION 
@@ -1 +1 @@ -2.1.4 +2.1.8 
diff --git a/include/sepol/policydb/polcaps.h b/include/sepol/policydb/polcaps.h index 40c0a48..f90a48d 100644 --- a/include/sepol/policydb/polcaps.h +++ b/include/sepol/policydb/polcaps.h 
@@ -5,6 +5,8 @@  enum { 	POLICYDB_CAPABILITY_NETPEER, 	POLICYDB_CAPABILITY_OPENPERM, +	POLICYDB_CAPABILITY_REDHAT1, /* reserved for RH testing of ptrace_child */ +	POLICYDB_CAPABILITY_ALWAYSNETWORK, 	__POLICYDB_CAPABILITY_MAX  };  #define POLICYDB_CAPABILITY_MAX (__POLICYDB_CAPABILITY_MAX - 1) 
diff --git a/include/sepol/policydb/policydb.h b/include/sepol/policydb/policydb.h index 1848a7b..f53a499 100644 --- a/include/sepol/policydb/policydb.h +++ b/include/sepol/policydb/policydb.h 
@@ -111,6 +111,19 @@ 	symtab_t permissions;	/* class-specific permission symbol table */ 	constraint_node_t *constraints;	/* constraints on class permissions */ 	constraint_node_t *validatetrans;	/* special transition rules */ +/* Options how a new object user and role should be decided */ +#define DEFAULT_SOURCE	1 +#define DEFAULT_TARGET	2 +	char default_user; +	char default_role; +/* Options how a new object range should be decided */ +#define DEFAULT_SOURCE_LOW	1 +#define DEFAULT_SOURCE_HIGH	2 +#define DEFAULT_SOURCE_LOW_HIGH	3 +#define DEFAULT_TARGET_LOW	4 +#define DEFAULT_TARGET_HIGH	5 +#define DEFAULT_TARGET_LOW_HIGH	6 +	char default_range;  } class_datum_t;    /* Role attributes */ @@ -667,10 +680,11 @@  #define POLICYDB_VERSION_BOUNDARY	24  #define POLICYDB_VERSION_FILENAME_TRANS	25  #define POLICYDB_VERSION_ROLETRANS	26 +#define POLICYDB_VERSION_NEW_OBJECT_DEFAULTS	27    /* Range of policy versions we understand*/  #define POLICYDB_VERSION_MIN	POLICYDB_VERSION_BASE -#define POLICYDB_VERSION_MAX	POLICYDB_VERSION_ROLETRANS +#define POLICYDB_VERSION_MAX	POLICYDB_VERSION_NEW_OBJECT_DEFAULTS    /* Module versions and specific changes*/  #define MOD_POLICYDB_VERSION_BASE	4 @@ -686,9 +700,10 @@  #define MOD_POLICYDB_VERSION_ROLETRANS	12  #define MOD_POLICYDB_VERSION_ROLEATTRIB	13  #define MOD_POLICYDB_VERSION_TUNABLE_SEP	14 +#define MOD_POLICYDB_VERSION_NEW_OBJECT_DEFAULTS	15    #define MOD_POLICYDB_VERSION_MIN MOD_POLICYDB_VERSION_BASE -#define MOD_POLICYDB_VERSION_MAX MOD_POLICYDB_VERSION_TUNABLE_SEP +#define MOD_POLICYDB_VERSION_MAX MOD_POLICYDB_VERSION_NEW_OBJECT_DEFAULTS    #define POLICYDB_CONFIG_MLS 1   
diff --git a/src/expand.c b/src/expand.c index 493e478..2003eb6 100644 --- a/src/expand.c +++ b/src/expand.c 
@@ -358,6 +358,35 @@ 	return -1;  }   +static int class_copy_default_new_object(expand_state_t *state, + class_datum_t *olddatum, + class_datum_t *newdatum) +{ +	if (olddatum->default_user) { +	if (newdatum->default_user && olddatum->default_user != newdatum->default_user) { +	ERR(state->handle, "Found conflicting default user definitions"); +	return SEPOL_ENOTSUP; +	} +	newdatum->default_user = olddatum->default_user; + +	} +	if (olddatum->default_role) { +	if (newdatum->default_role && olddatum->default_role != newdatum->default_role) { +	ERR(state->handle, "Found conflicting default role definitions"); +	return SEPOL_ENOTSUP; +	} +	newdatum->default_role = olddatum->default_role; +	} +	if (olddatum->default_range) { +	if (newdatum->default_range && olddatum->default_range != newdatum->default_range) { +	ERR(state->handle, "Found conflicting default range definitions"); +	return SEPOL_ENOTSUP; +	} +	newdatum->default_range = olddatum->default_range; +	} +	return 0; +} +  static int class_copy_callback(hashtab_key_t key, hashtab_datum_t datum,  void *data)  { @@ -393,6 +422,12 @@ 	new_class->s.value = class->s.value; 	state->out->p_classes.nprim++;   +	ret = class_copy_default_new_object(state, class, new_class); +	if (ret) { +	free(new_class); +	return ret; +	} + 	new_id = strdup(id); 	if (!new_id) { 	ERR(state->handle, "Out of memory!"); @@ -688,6 +723,11 @@ 	return 0; 	}   +	if (!is_id_enabled(id, state->base, SYM_ROLES)) { +	/* identifier's scope is not enabled */ +	return 0; +	} + 	if (role->flavor != ROLE_ATTRIB) 	return 0;   @@ -1317,16 +1357,11 @@  static int expand_filename_trans(expand_state_t *state, filename_trans_rule_t *rules)  { 	unsigned int i, j; -	filename_trans_t *new_trans, *tail, *cur_trans; +	filename_trans_t *new_trans, *cur_trans; 	filename_trans_rule_t *cur_rule; 	ebitmap_t stypes, ttypes; 	ebitmap_node_t *snode, *tnode;   -	/* start at the end of the list */ -	tail = state->out->filename_trans; -	while (tail && tail->next) -	tail = tail->next; - 	cur_rule = rules; 	while (cur_rule) { 	uint32_t mapped_otype; @@ -1387,11 +1422,8 @@ 	return -1; 	} 	memset(new_trans, 0, sizeof(*new_trans)); -	if (tail) -	tail->next = new_trans; -	else -	state->out->filename_trans = new_trans; -	tail = new_trans; +	new_trans->next = state->out->filename_trans; +	state->out->filename_trans = new_trans;   	new_trans->name = strdup(cur_rule->name); 	if (!new_trans->name) { @@ -1791,58 +1823,36 @@ 	continue; 	if (source_rule->flags & RULE_SELF) { 	if (source_rule->specified & AVRULE_AV) { -	if ((retval = - expand_avrule_helper(handle, - source_rule-> - specified, cond, i, i, - source_rule->perms, - dest_avtab, - enabled)) != - EXPAND_RULE_SUCCESS) { +	retval = expand_avrule_helper(handle, source_rule->specified, + cond, i, i, source_rule->perms, + dest_avtab, enabled); +	if (retval != EXPAND_RULE_SUCCESS) 	return retval; -	} 	} else { -	if ((retval = - expand_terule_helper(handle, p, - typemap, - source_rule-> - specified, cond, - other, i, i, - source_rule->perms, - dest_avtab, - enabled)) != - EXPAND_RULE_SUCCESS) { +	retval = expand_terule_helper(handle, p, typemap, + source_rule->specified, cond, + other, i, i, source_rule->perms, + dest_avtab, enabled); +	if (retval != EXPAND_RULE_SUCCESS) 	return retval; -	} 	} 	} 	ebitmap_for_each_bit(ttypes, tnode, j) { 	if (!ebitmap_node_get_bit(tnode, j)) 	continue; 	if (source_rule->specified & AVRULE_AV) { -	if ((retval = - expand_avrule_helper(handle, - source_rule-> - specified, cond, i, j, - source_rule->perms, - dest_avtab, - enabled)) != - EXPAND_RULE_SUCCESS) { +	retval = expand_avrule_helper(handle, source_rule->specified, + cond, i, j, source_rule->perms, + dest_avtab, enabled); +	if (retval != EXPAND_RULE_SUCCESS) 	return retval; -	} 	} else { -	if ((retval = - expand_terule_helper(handle, p, - typemap, - source_rule-> - specified, cond, - other, i, j, - source_rule->perms, - dest_avtab, - enabled)) != - EXPAND_RULE_SUCCESS) { +	retval = expand_terule_helper(handle, p, typemap, + source_rule->specified, cond, + other, i, j, source_rule->perms, + dest_avtab, enabled); +	if (retval != EXPAND_RULE_SUCCESS) 	return retval; -	} 	} 	} 	} @@ -2027,13 +2037,14 @@ 	else 	state->out->ocontexts[i] = n; 	l = n; -	if (context_copy(&n->context[0], &c->context[0], -	state)) { -	ERR(state->handle, "Out of memory!"); -	return -1; -	} 	switch (i) { 	case OCON_XEN_ISID: +	if (c->context[0].user == 0) { +	ERR(state->handle, + "Missing context for %s initial sid", + c->u.name); +	return -1; +	} 	n->sid[0] = c->sid[0]; 	break; 	case OCON_XEN_PIRQ: @@ -2056,6 +2067,11 @@ 	ERR(state->handle, "Unknown ocontext"); 	return -1; 	} +	if (context_copy(&n->context[0], &c->context[0], +	state)) { +	ERR(state->handle, "Out of memory!"); +	return -1; +	} 	} 	} 	return 0; @@ -2080,12 +2096,14 @@ 	else 	state->out->ocontexts[i] = n; 	l = n; -	if (context_copy(&n->context[0], &c->context[0], state)) { -	ERR(state->handle, "Out of memory!"); -	return -1; -	} 	switch (i) { 	case OCON_ISID: +	if (c->context[0].user == 0) { +	ERR(state->handle, + "Missing context for %s initial sid", + c->u.name); +	return -1; +	} 	n->sid[0] = c->sid[0]; 	break; 	case OCON_FS:	/* FALLTHROUGH */ @@ -2129,6 +2147,10 @@ 	ERR(state->handle, "Unknown ocontext"); 	return -1; 	} +	if (context_copy(&n->context[0], &c->context[0], state)) { +	ERR(state->handle, "Out of memory!"); +	return -1; +	} 	} 	} 	return 0; @@ -3101,12 +3123,12 @@ 	newkey.target_class = k->target_class; 	newkey.specified = k->specified;   -	if (stype && ttype) { +	if (stype->flavor != TYPE_ATTRIB && ttype->flavor != TYPE_ATTRIB) { 	/* Both are individual types, no expansion required. */ 	return expand_avtab_insert(expa, k, d); 	}   -	if (stype) { +	if (stype->flavor != TYPE_ATTRIB) { 	/* Source is an individual type, target is an attribute. */ 	newkey.source_type = k->source_type; 	ebitmap_for_each_bit(tattr, tnode, j) { @@ -3120,7 +3142,7 @@ 	return 0; 	}   -	if (ttype) { +	if (ttype->flavor != TYPE_ATTRIB) { 	/* Target is an individual type, source is an attribute. */ 	newkey.target_type = k->target_type; 	ebitmap_for_each_bit(sattr, snode, i) { @@ -3231,12 +3253,12 @@ 	newkey.target_class = k->target_class; 	newkey.specified = k->specified;   -	if (stype && ttype) { +	if (stype->flavor != TYPE_ATTRIB && ttype->flavor != TYPE_ATTRIB) { 	/* Both are individual types, no expansion required. */ 	return expand_cond_insert(newl, expa, k, d); 	}   -	if (stype) { +	if (stype->flavor != TYPE_ATTRIB) { 	/* Source is an individual type, target is an attribute. */ 	newkey.source_type = k->source_type; 	ebitmap_for_each_bit(tattr, tnode, j) { @@ -3250,7 +3272,7 @@ 	return 0; 	}   -	if (ttype) { +	if (ttype->flavor != TYPE_ATTRIB) { 	/* Target is an individual type, source is an attribute. */ 	newkey.target_type = k->target_type; 	ebitmap_for_each_bit(sattr, snode, i) { 
diff --git a/src/link.c b/src/link.c index ee9675b..01d3231 100644 --- a/src/link.c +++ b/src/link.c 
@@ -205,6 +205,34 @@ 	return ret;  }   +static int class_copy_default_new_object(link_state_t *state, + class_datum_t *olddatum, + class_datum_t *newdatum) +{ +	if (olddatum->default_user) { +	if (newdatum->default_user && olddatum->default_user != newdatum->default_user) { +	ERR(state->handle, "Found conflicting default user definitions"); +	return SEPOL_ENOTSUP; +	} +	newdatum->default_user = olddatum->default_user; +	} +	if (olddatum->default_role) { +	if (newdatum->default_role && olddatum->default_role != newdatum->default_role) { +	ERR(state->handle, "Found conflicting default role definitions"); +	return SEPOL_ENOTSUP; +	} +	newdatum->default_role = olddatum->default_role; +	} +	if (olddatum->default_range) { +	if (newdatum->default_range && olddatum->default_range != newdatum->default_range) { +	ERR(state->handle, "Found conflicting default range definitions"); +	return SEPOL_ENOTSUP; +	} +	newdatum->default_range = olddatum->default_range; +	} +	return 0; +} +  static int class_copy_callback(hashtab_key_t key, hashtab_datum_t datum,  void *data)  { @@ -287,6 +315,11 @@ 	state->dest_class = new_class; 	state->dest_class_name = (char *)key;   +	/* copy default new object rules */ +	ret = class_copy_default_new_object(state, cladatum, new_class); +	if (ret) +	return ret; + 	ret =  hashtab_map(cladatum->permissions.table, permission_copy_callback, 	state); 
diff --git a/src/polcaps.c b/src/polcaps.c index 71970b1..43a71a7 100644 --- a/src/polcaps.c +++ b/src/polcaps.c 
@@ -8,6 +8,8 @@  static const char *polcap_names[] = { 	"network_peer_controls",	/* POLICYDB_CAPABILITY_NETPEER */ 	"open_perms",	/* POLICYDB_CAPABILITY_OPENPERM */ +	"redhat1",	/* POLICYDB_CAPABILITY_REDHAT1, aka ptrace_child */ +	"always_check_network",	/* POLICYDB_CAPABILITY_ALWAYSNETWORK */ 	NULL  };   
diff --git a/src/policydb.c b/src/policydb.c index 136b450..ff292f6 100644 --- a/src/policydb.c +++ b/src/policydb.c 
@@ -151,6 +151,13 @@  .target_platform = SEPOL_TARGET_SELINUX, 	}, 	{ + .type = POLICY_KERN, + .version = POLICYDB_VERSION_NEW_OBJECT_DEFAULTS, + .sym_num = SYM_NUM, + .ocon_num = OCON_NODE6 + 1, + .target_platform = SEPOL_TARGET_SELINUX, +	}, +	{  .type = POLICY_BASE,  .version = MOD_POLICYDB_VERSION_BASE,  .sym_num = SYM_NUM, @@ -228,6 +235,13 @@  .target_platform = SEPOL_TARGET_SELINUX, 	}, 	{ + .type = POLICY_BASE, + .version = MOD_POLICYDB_VERSION_NEW_OBJECT_DEFAULTS, + .sym_num = SYM_NUM, + .ocon_num = OCON_NODE6 + 1, + .target_platform = SEPOL_TARGET_SELINUX, +	}, +	{  .type = POLICY_MOD,  .version = MOD_POLICYDB_VERSION_BASE,  .sym_num = SYM_NUM, @@ -304,6 +318,13 @@  .ocon_num = 0,  .target_platform = SEPOL_TARGET_SELINUX, 	}, +	{ + .type = POLICY_MOD, + .version = MOD_POLICYDB_VERSION_NEW_OBJECT_DEFAULTS, + .sym_num = SYM_NUM, + .ocon_num = 0, + .target_platform = SEPOL_TARGET_SELINUX, +	},  };    #if 0 @@ -2064,6 +2085,18 @@ 	goto bad; 	}   +	if ((p->policy_type == POLICY_KERN && + p->policyvers >= POLICYDB_VERSION_NEW_OBJECT_DEFAULTS) || + (p->policy_type == POLICY_BASE && + p->policyvers >= MOD_POLICYDB_VERSION_NEW_OBJECT_DEFAULTS)) { +	rc = next_entry(buf, fp, sizeof(uint32_t) * 3); +	if (rc < 0) +	goto bad; +	cladatum->default_user = le32_to_cpu(buf[0]); +	cladatum->default_role = le32_to_cpu(buf[1]); +	cladatum->default_range = le32_to_cpu(buf[2]); +	} + 	if (hashtab_insert(h, key, cladatum)) 	goto bad;   @@ -2347,7 +2380,7 @@ 	return -1; 	len = le32_to_cpu(buf[0]);   -	name = calloc(len, sizeof(*name)); +	name = calloc(len + 1, sizeof(*name)); 	if (!name) 	return -1;   
diff --git a/src/private.h b/src/private.h index a2188d4..8a6d4bb 100644 --- a/src/private.h +++ b/src/private.h 
@@ -18,7 +18,7 @@    #ifdef DARWIN  #define __BYTE_ORDER BYTE_ORDER -#define __LITTLE_ENDIAN LITTLE_ENDIAN  +#define __LITTLE_ENDIAN LITTLE_ENDIAN  #endif    #if __BYTE_ORDER == __LITTLE_ENDIAN 
diff --git a/src/write.c b/src/write.c index e34ab52..22e6143 100644 --- a/src/write.c +++ b/src/write.c 
@@ -976,6 +976,18 @@ 	return POLICYDB_ERROR; 	}   +	if ((p->policy_type == POLICY_KERN && + p->policyvers >= POLICYDB_VERSION_NEW_OBJECT_DEFAULTS) || + (p->policy_type == POLICY_BASE && + p->policyvers >= MOD_POLICYDB_VERSION_NEW_OBJECT_DEFAULTS)) { +	buf[0] = cpu_to_le32(cladatum->default_user); +	buf[1] = cpu_to_le32(cladatum->default_role); +	buf[2] = cpu_to_le32(cladatum->default_range); +	items = put_entry(buf, sizeof(uint32_t), 3, fp); +	if (items != 3) +	return POLICYDB_ERROR; +	} + 	return POLICYDB_SUCCESS;  }